using System.Collections.Generic;
using GameFramework.Battle.Core;
using Gameplay.PVE.Entity;
using Gameplay.PVE.Utils;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.EventSystems;
using UnityEngine.PlayerLoop;
using Yoozoo.Libs;
using Yoozoo.Managers;
using Yoozoo.Gameplay.RTS;
using Random = UnityEngine.Random;

namespace Gameplay.PVE
{
    public class MoveComponent:IComponent,ITransmit
    {
        //位置相关控件
        protected UnitBase unit;

        private List<Vector3> pathList = new List<Vector3>();
        private List<Vector3> newPathList = new List<Vector3>();
        protected UnitRoadPath roadPath;
        private ControlBehaviour controlBehaviour;
        
        private float turnStartTime;
        private float turnStayTime = 1.042f;

        private float startSpawnTime;

        private bool isSquat = false;
        private float startSquatTime;
        private float squatTime = 0.5f;
        private float squatUpTime = 0.4f;

        void IClass.OnReset()
        {
            if (roadPath != null)
            {
                ClassManager.Free(roadPath);
                roadPath = null;
            }

            if (controlBehaviour != null)
            {
                ClassManager.Free(controlBehaviour);
                controlBehaviour = null;
            }
            
            startSpawnTime = 0;
            isSquat = false;
        }

        void IComponent.OnInitialize(UnitBase unit)
        {
            this.unit = unit;
        }

        void IComponent.OnUpdate()
        {
            if (unit.Data.isDead)
            {
                return;
            }

            OnUpdate();
        }

        protected virtual void OnUpdate()
        {
            controlBehaviour?.Update();
            UpdateSpawning();
            UpdateSquat();
        }

        
        //正在出生中
        private void UpdateSpawning()
        {
            if (startSpawnTime != 0)
            {
                float spawnDelay = 0.1f;
                if (TimeManager.logicTime - startSpawnTime > spawnDelay)
                {
                    startSpawnTime = 0;
                    unit.Data.isShowingSpawn = false;
                    unit.Transmit(ETransmitType.ShowHud);
                }
            }
        }

        //下蹲状态处理
        private void UpdateSquat()
        {
            if (isSquat)
            {
                unit.Data.moveSpeed = 0;
                if (startSquatTime != 0 && TimeManager.logicTime - startSquatTime >= squatTime)
                {
                    unit.Data.isInAction = false;
                    unit.Data.isGoingToHidePoint = false;
                    startSquatTime = 0;
                    unit.Data.SetIsInAttack(false);
                }
            }
            else
            {
                if (startSquatTime != 0)
                {
                    if (TimeManager.logicTime - startSquatTime >= squatUpTime)
                    {
                        unit.Data.isInAction = false;
                        startSquatTime = 0;
                        unit.Data.SetIsInAttack(false);
                    }
                    unit.Data.moveSpeed = 0;
                }
            }
        }
        
       
        
        void IComponent.OnBirth()
        {
            
            unit.Data.forward = Vector3.forward;
            unit.Data.position = unit.Data.birthPosition;
            unit.Data.SetTargetPosition(unit.Data.birthPosition);

            unit.gameObject.transform.position = unit.Data.position;
            if (unit.Data.unitType == 0)
            {
                unit.Data.position = unit.Data.birthPosition;
                if (this is HangingMoveComponent)
                {
                    if (unit.Data.id == 0)
                    {
                        roadPath = ClassManager.Get<SimpleRoadPath>();//主角挂机寻路
                    }
                    else if (unit.Data.team == 0)
                    {
                        roadPath = ClassManager.Get<FollowRoadPath>();//小弟跟随
                    }
                    else
                    {
                        roadPath = ClassManager.Get<SimpleRoadPath>();//敌方挂机寻路
                    }
                }
                else
                {
                    if (unit.Data.team == 0)
                    {
                        /*if (unit.Data.rangeType == 0)
                        {
                            
                        }*/
                        roadPath = ClassManager.Get<AStarRoadPath>();//我方移动射击寻路
                    }
                    else
                    {
                        roadPath = ClassManager.Get<AStarRoadPath>();//敌方战斗寻路
                    }
                   
                }

                if (PveManager.Instance.isInRpg)
                {
                    unit.Data.SetTargetForward(new Vector3(1 - unit.Data.team, 0, 0).normalized);
                    unit.Data.forward = unit.Data.targetForward;
                }
                else
                {
                    if  (unit.Data.team == 0)
                    {
                        unit.Data.SetTargetForward(Vector3.right);
                        unit.Data.forward = Vector3.right;
                    }
                    else
                    {
                        unit.Data.SetTargetForward(new Vector3(Random.Range(-1f, 1f), 0, Random.Range(-1f, 1f)).normalized);
                        unit.Data.forward = unit.Data.targetForward;
                    }
                    
                }
               
            }
            else if (unit.Data.unitType == 1)
            {
                unit.Data.position = unit.Data.birthPosition;
                roadPath = ClassManager.Get<MortalRoadPath>();
                unit.Data.moveSpeed = Random.Range(0.8f, 1.2f) * PveUtils.globalRatio;
                unit.Data.forward = new Vector3(Random.Range(-1f,1f),0,Random.Range(-1f,1f)).normalized;
                
            }
            else if (unit.Data.unitType == 2)
            {
                roadPath = ClassManager.Get<VehicleRoadPath>();
                unit.Data.moveSpeed = 5 * PveUtils.globalRatio;
            }
            else if (unit.Data.unitType == 4)
            {
                unit.Data.position = unit.Data.birthPosition;
                unit.Data.SetTargetForward(new Vector3(0,0,1));
            }
           
            if (roadPath == null)
            {
                Debug.Log("roadPath " + unit.Data.unitType);
            }
            roadPath?.Init(this.unit);
            controlBehaviour = ClassManager.Get<ControlBehaviour>();
            controlBehaviour.Init(unit);
            unit.gameObject.transform.position = unit.Data.position;
            unit.gameObject.transform.forward = unit.Data.forward;
            OnBirth();
        }

        void IComponent.OnDead()
        {
            OnDead();
        }

        protected virtual void OnDead()
        {
            roadPath?.OnDead();
        }

        protected virtual void OnBirth()
        {
            
        }

        private void SquatStart()
        {
            if (unit is BattleUnit battleUnit)
            {
                //battleUnit.Play("Idle");
                battleUnit.SetAnimatorBool("Squat", true);
                battleUnit.Data.isInAction = true;
                if (unit.Data.lockTarget != null)
                {
                    unit.Data.SetTargetForward(unit.Data.lockTarget.Data.position - unit.Data.position);
                }
                startSquatTime = TimeManager.logicTime;
            }
        }

        private void SquatEnd()
        {
            if (unit is BattleUnit battleUnit)
            {
                battleUnit.SetAnimatorBool("Squat", false);
                battleUnit.Data.isInAction = true;
                battleUnit.Data.SetIsCanMove(true);
                startSquatTime = TimeManager.logicTime;
            }
        }
        
        protected void UpdateForward()
        {
            if (unit.Data.IsInControl())
            {
                return;
            }
            if (turnStartTime != 0 && TimeManager.logicTime - turnStartTime > turnStayTime)
            {
                unit.Play("Idle",1);
                turnStartTime = 0;
            }

            float angleSpeedRatio = 1;
            if (unit.Data.manualAimForward.sqrMagnitude > 0)
            {
                angleSpeedRatio = 2;
            }
            if (unit.Data.targetForward != unit.Data.forward)
            {
                float diffAngle = PveUtils.GetAngle(unit.Data.forward,unit.Data.targetForward);
                if (diffAngle != 0)
                {
                    float angleSpeed = unit.Data.angleSpeed;
                    if (PveManager.Instance.isInRpg && unit.Data.isManualMoving)
                    {
                        angleSpeed = 1000;
                    }
                    float angle = angleSpeed * angleSpeedRatio * TimeManager.LogicDeltaTime * diffAngle / Mathf.Abs(diffAngle);
                    if (Mathf.Abs(diffAngle) <= Mathf.Abs(angle))
                    {
                        unit.Data.forward = unit.Data.targetForward;
                    }
                    else
                    {
                        unit.Data.forward = Quaternion.AngleAxis(angle, Vector3.up) * unit.Data.forward;
                    }

                    if (turnStartTime == 0 && false)// && !PveManager.Instance.isInRpg)
                    {
                        if (diffAngle > 40)
                        {
                            turnStartTime = TimeManager.logicTime;
                            float speed = 180 / Mathf.Abs(diffAngle);
                            turnStayTime = 1.042f / speed;
                            unit.Play("TurnRight",speed);
                        }
                        else if (diffAngle < -40)
                        {
                            float speed = 180 / Mathf.Abs(diffAngle);
                            turnStayTime = 1.042f / speed;
                            unit.Play("TurnLeft",speed);
                            turnStartTime = TimeManager.logicTime;
                        }
                    }
                }
                else
                {
                    unit.Data.forward = unit.Data.targetForward;
                }
            }

        }
        private void UpdateMoveState()
        {
            if (unit.Data.isManualMoving)//手操的人，由摇杆控制状态
            {
                return;
            }

            if (unit.Data.moveState == 1 || unit.Data.moveState == 3 || unit.Data.moveState == 4 || unit.Data.moveState == 5)
            {
                unit.Data.RemoveAstar();
                return;
            }
            
            if (unit.Data.isReloading || unit.Data.IsInAttack() || !unit.Data.IsInitiative() || isSquat || !unit.Data.IsCanMove() || unit.Data.IsInSkill() || unit.Data.isInAction)
            {
                unit.Data.moveState = -1;
                unit.Data.AddAstar();
            }
            else if (unit.Data.isMoveAttacking)
            {
                unit.Data.moveState = 1;
                unit.Data.AddAstar();
            }
            else
            {
                /*if (unit.Data.moveState == 2)
                {
                    unit.Data.RemoveAstar();
                }*/
            }
            /*else if (unit.Data.lockTarget == null || !unit.Data.IsAttackInRange() || unit.Data.isGoingToHidePoint)
            {
                unit.Data.moveState = 2;
            }*/
            
        }

        

        protected void UpdatePosition()
        {
            if (roadPath == null)
            {
                return;
            }

            if (unit.Data.isShowingSpawn)
            {
                return;
            }
            
            if (turnStartTime != 0)
            {
                return;
            }
            
            if (!unit.Data.IsInitiative())
            {
                roadPath.position = unit.Data.position;
                return;
            }

            if (Vector3.Distance(unit.Data.hidePosition,unit.Data.position) <= 0.01f && unit.Data.lockTarget != null && unit.Data.IsAttackInRange())
            {
                unit.Transmit(ETransmitType.HideIn);
                unit.Data.moveState = 0;
                unit.Data.isHiding = true;
                if (!isSquat)
                {
                    //unit.Data.GoInHidePoint();
                    isSquat = true;
                    unit.Data.hidingObstacle = unit.Data.readyTohideObstacle;
                    SquatStart();
                    unit.Data.hasReachAttackPosition = true;
                }
            }
            else
            {
                if (isSquat && !unit.Data.IsInAttack() && !unit.Data.isReloading)
                {
                    unit.Data.isHiding = false;
                    //unit.Data.LeaveHidePoint();
                    //if (!unit.Data.isGoingToHidePoint)
                    {
                        unit.Data.hidingObstacle = null;
                    }
                    isSquat = false;
                    SquatEnd();
                }
                unit.Transmit(ETransmitType.HideOut);
                unit.Data.isHiding = false;
            }
            UpdateMoveState();

            if (unit.Data.moveState == -1 || unit.Data.moveState == 3 || unit.Data.moveState == 4 || unit.Data.moveState == 5)
            {
                if (unit.Data.isApplyAnimationMovement)
                {
                    var newPosition = unit.Data.position + unit.Data.moveOffset;
                    if (PveFindPathManager.Instance.CheckIsWalkable(newPosition, unit.Data.id,AStarBlockType.Ground) && PveManager.Instance.IsInBattleRegion(newPosition))
                    {
                        unit.Data.position = newPosition;
                    }
                }
                roadPath.position = unit.Data.position;
                return;
            }
            else
            {
                roadPath.Update();
            }
            
            
            if (unit.Data.moveState == 0 && !unit.Data.isMoveAttacking)
            {
                /*if (Vector3.Distance(unit.Data.position,unit.Data.targetHidingPoint) < 0.01)
                {
                    unit.Data.targetHidingPoint = Vector3.zero;
                }*/
                
                //CheckOrder();
                if (!unit.Data.IsInAttack() && !unit.Data.IsInSkill() && !(unit.Data.team == 0 && PveManager.Instance.isInPve) && !unit.Data.IsAttackInRange())
                {
                    unit.Play("Idle");
                }
            }
            else
            {
                if (PveManager.Instance.isInRpg)//限制角色走位
                {
                    var needIdle = false;
                    /*if (unit.Data.config.posType == 0)
                    {
                        PositionRestriction(2,13,-6,4,unit.Data.isManualMoving);
                    }
                    else
                    {
                        PositionRestriction(-1,13,-6,4);
                    }*/
                    /*if (needIdle)
                    {
                        unit.Play("Idle");
                        unit.Data.moveState = 0;
                    }*/
                    if (needIdle)
                    {
                        roadPath.position = unit.Data.position;
                    }
                }

                if ((Vector3.Distance(roadPath.position, unit.Data.position) < 0.0001f) && !unit.Data.IsAttackInRange())
                {
                    //unit.Play("Idle");
                }
                else if (unit.Data.moveState == 1 || (!unit.Data.IsInAttack() && !unit.Data.IsInSkill() && (!unit.Data.isReloading || unit.Data.isManualMoving)))
                {
                    //unit.Play(roadPath.actionName,roadPath.actionSpeed);
                    unit.Transmit(ETransmitType.Move);
                }
            }
            unit.Data.position = roadPath.position;
        }
        
        private GameObject fightingCordonEffect;
        private float deactiveTimer = 1f;
        private float activeTimer = 1f;
        private float enterTimer = 1f;
        
        private void LoadFightingCordonEffect()
        {
            fightingCordonEffect = PveResourceManager.GetResource(PveResourceManager.EPveResType.Pointer, 7);
            fightingCordonEffect.transform.SetParent(PveManager.Instance.mainUnit.gameObject.transform.parent.transform);
            fightingCordonEffect.transform.localScale = new Vector3(1,1,4);
            fightingCordonEffect.SetActive(false);
        }

        private void DeactiveFightingCordonEffect()
        {
            deactiveTimer += TimeManager.GameDeltaTime;
            if (deactiveTimer > 1)
            {
                deactiveTimer = 0;
                fightingCordonEffect.SetActive(false);
            }
        }
        
        private void ActiveFightingCordonEffect()
        {
            activeTimer += TimeManager.GameDeltaTime;
            if (activeTimer > 1)
            {
                activeTimer = 0;
                fightingCordonEffect.SetActive(true);
            }
        }
        
        /// <summary>
        /// 限制角色的移动边界并显示障碍效果
        /// </summary>
        /// <param name="xStart">右边界</param>
        /// <param name="xEnd">左边界</param>
        /// <param name="zStart">上边界</param>
        /// <param name="zEnd">下边界</param>
        private bool PositionRestriction(float xStart = 2f, float xEnd = 9f, float zStart = -6f, float zEnd = 4f,bool showEffect = false)
        {
            //Bug: 队友和主角一起踩到边界，会出现两个障碍效果
            if (showEffect)
            {
                if (fightingCordonEffect == null)
                    LoadFightingCordonEffect();
                fightingCordonEffect.transform.position = PveManager.Instance.GetRpgStageCenterPosition() - new Vector3(xStart - 0.5f, 0, 0);
            }
            Vector3 updatePosition = roadPath.position;
            bool isRestrict = false;
            //设置左边界和上边界
            var startPosition = PveManager.Instance.GetRpgStageCenterPosition() - new Vector3(xStart, 0, zStart);
            if (roadPath.position.x - startPosition.x >= 0)
            {
                isRestrict = true;
                updatePosition.x = startPosition.x;
                if (showEffect)
                {
                    if (fightingCordonEffect.activeSelf)
                    {
                        DeactiveFightingCordonEffect();
                    }
                    else
                    {
                        ActiveFightingCordonEffect();
                    }
                }
            }
            else
            {
                enterTimer += TimeManager.GameDeltaTime;
                if (showEffect)
                {
                    if (enterTimer > 1)
                    {
                        //进出CD到时，将障碍显示效果设置为可以立即触发的状态
                        fightingCordonEffect.SetActive(false);
                        enterTimer = 0;
                        activeTimer = 1;
                        deactiveTimer = 0;
                    }
                    else
                    {
                        if (fightingCordonEffect.activeSelf)
                        {
                            DeactiveFightingCordonEffect();
                        }
                    }
                }
                
            }
            if (roadPath.position.z - startPosition.z >= 0)
            {
                isRestrict = true;
                updatePosition.z = startPosition.z;
            }
            
            //设置右边界和下边界
            var endPosition = PveManager.Instance.GetRpgStageCenterPosition() - new Vector3(xEnd, 0, zEnd);
            if (roadPath.position.x - endPosition.x <= 0)
            {
                isRestrict = true;
                updatePosition.x = endPosition.x;
            }
            if (roadPath.position.z - endPosition.z <= 0)
            {
                isRestrict = true;
                updatePosition.z = endPosition.z;
            }
            
            //更新位置
            bool needIdle = Vector3.Distance(updatePosition, roadPath.position) < 0.01f && isRestrict;
            roadPath.position = updatePosition;
            return needIdle;
        }


        private float startTime;
        private float nextPointTime;
        private float pointStartTime;
        private int nextIndex;
        private bool needNextFrameSetRoadPath = false;


        
        /*private void UpdateRoadPath()
        {
            if (!unit.Data.IsCanMove())
            {
                return;
            }

            if (needNextFrameSetRoadPath)
            {
                NextFrameSetRoadPath();
                needNextFrameSetRoadPath = false;
            }
            else if (TimeManager.logicTime - lastUpdateRoadPathTime > 0.5f && lastTargetPosition != unit.Data.targetPosition)
            {
                SetRoadPath();
            }

            if (Vector3.Distance(unit.Data.targetPosition,unit.Data.position) <= 0.01f)
            {
                if (unit.Data.lockTarget != null)
                {
                    
                }
                else if (!unit.Data.IsInSkill())
                {
                    //if (!CheckIsInPatrol())
                    {
                        unit.Play("Idle");
                    }
                }
                CheckHasOrder();
                return;
            }
            
            if (pathList.Count > nextIndex && nextIndex > 0)
            {
                Vector3 targetPosition = pathList[nextIndex];
                Vector3 lastPosition = pathList[nextIndex - 1];
                float percent = (TimeManager.logicTime - pointStartTime) / nextPointTime;
                if (percent <= 1)
                {
                    unit.Data.position = lastPosition + (targetPosition - lastPosition) * percent;
                }
                else
                {
                    pointStartTime = TimeManager.logicTime;
                    ToNextPoint();
                }
            }
            unit.Play("Walk");
            //if (lastTargetPosition != unit.Data.targetPosition)
            {
                //lastTargetPosition = unit.Data.targetPosition;
                //SetRoadPath();
            }
        }*/


    
        
        private void CheckOrder()
        {
            var orders = unit.Data.GetOrders();
            if (orders.Count > 0)
            {
                var currentOrder = orders[0];
                if (currentOrder.type == UnitOrder.EOrderType.Park)
                {
                    if (TimeManager.logicTime - currentOrder.startTime >= currentOrder.lastTime)
                    {
                        orders.RemoveAt(0);
                    }
                }
                else if (currentOrder.type == UnitOrder.EOrderType.Patrol)
                {
                    if (Vector3.Distance(unit.Data.position, currentOrder.targetPosition) < unit.Data.attackRange * 2)
                    {
                        orders.RemoveAt(0);
                    }
                }
                else if (currentOrder.type == UnitOrder.EOrderType.Skill)
                {
                    return;
                }
                else if (currentOrder.type == UnitOrder.EOrderType.Follow)
                {
                    if (roadPath is FollowRoadPath path)
                    {
                        path.RefreshFollow();
                    }
                }
                else if (currentOrder.type == UnitOrder.EOrderType.MoveToPosition)
                {
                    if (unit.Data.position == currentOrder.targetPosition)
                    {
                        orders.RemoveAt(0);
                        return;
                    }
                }
            }

            if (orders.Count > 0)
            {
                ObeyOrder(orders[0]);
            }
            else if (unit.Data.unitType == 1)
            {
                AddMortalAction();
            }
        }

        private bool CheckPatrolState()
        {
            var orderList = unit.Data.GetOrders();
            for (int i = 0; i < orderList.Count; i++)
            {
                if (orderList[i].type == UnitOrder.EOrderType.Patrol)
                {
                    return true;
                }
            }

            return false;
        }
        
        void ITransmit.OnTransmit(ETransmitType type, BaseTransmitArg arg)
        {
            OnTransmit(type, arg);
        }

        protected virtual void OnTransmit(ETransmitType type, BaseTransmitArg arg)
        {
            if (type == ETransmitType.AddOrder)
            {
                var order = ((AddOrderTransmitArg) arg).order;
                AddOrder(order);
            }
            else if (type == ETransmitType.RpgStageToNext)
            {
                if (unit.Data.id != 0)
                {
                    return;
                }
                unit.Data.ClearOrders();
                //unit.Data.SetIsInAttack(false);
                unit.Data.SetLockTarget(null);
                /*var list = PveManager.Instance.GetMyRoadPath(unit.Data.id);
                if (list.Count > 0)
                {
                    var targetPosition = list[list.Count - 1];
                    unit.Data.SetTargetPosition(targetPosition);
                    unit.Data.patrolPosition = targetPosition;
                    unit.Data.birthPosition = targetPosition;
                    unit.Data.isInBirthPosition = false;
                }*/
            }
            else if (type == ETransmitType.ToRPG)
            {
                //if (unit.Data.team == 0)
                {
                    unit.Data.ClearOrders();
                    //unit.Data.SetIsInAttack(false);
                    unit.Data.SetLockTarget(null);
                    //unit.Data.SetTargetPosition(PveManager.Instance.GetRpgBirthPosition(unit.Data.stage,unit.Data.team,unit.Data.index));
                    unit.Data.SetIsCanMove(true);
                    unit.Data.moveSpeedRatio = 1;
                    //unit.Data.moveState = 2;
                    unit.Data.SetTargetForward(unit.Data.team == 0 ? Vector3.right : Vector3.left);
                    unit.Data.forward = unit.Data.targetForward;
                    unit.gameObject.transform.forward = unit.Data.forward;
                    unit.Data.isInBirthPosition = false;
                }
            }
            else if (type == ETransmitType.RpgWin)
            {
                unit.Data.SetTargetPosition(unit.Data.position);
                unit.Data.manualForward = Vector3.zero;
                unit.Data.moveState = 0;
                unit.Data.SetLockTarget(null);
            }
            else if (type == ETransmitType.RpgLose)
            {
                unit.Data.moveState = 0;
            }
            else if (type == ETransmitType.RpgToNext)
            {
                unit.Data.ClearOrders();
                unit.Data.birthPosition = unit.Data.targetPosition;
                //unit.Data.SetIsCanMove(true);
            }
            else if (type == ETransmitType.AddControl)
            {
                controlBehaviour.AddControl(arg as AddControlArg);
            }
            else if (type == ETransmitType.RemoveControl)
            {
                controlBehaviour.RemoveControl(arg as RemoveControllArg);
            }
            else if (type == ETransmitType.SpawnInStage)
            {
                unit.Data.isShowingSpawn = true;
                startSpawnTime = TimeManager.logicTime;
                unit.Play("Cele");
            }
            else if (type == ETransmitType.SquatUp)
            {
                isSquat = false;
                SquatEnd();
            }
            else if (type == ETransmitType.SwitchToPve)
            {
                var position = Vector3.zero;
                unit.Data.position = position;
                roadPath.position = position;
                unit.gameObject.transform.position = unit.Data.position;
                unit.gameObject.transform.forward = unit.Data.forward;
                unit.Data.SetIsInSkill(false);
                unit.Data.SetIsInAttack(false);
                unit.Data.SetIsCanMove(true);
                unit.Data.moveState = 0;
                unit.Data.controlType = EControlType.None;
            }
            else if (type == ETransmitType.SwitchToRpg)
            {
                if (PveGlobalVlues.SelfRunIntoBattle)
                {
                    var position = unit.Data.birthPosition + new Vector3(-5, 0, 0);
                    unit.Data.position = position;
                    roadPath.position = position;
                    unit.Data.isInBirthPosition = false;
                    unit.gameObject.transform.position = unit.Data.position;
                    unit.gameObject.transform.forward = unit.Data.forward;
                    unit.Data.moveState = 2;
                }
                else
                {
                    unit.Data.moveState = 0;
                    unit.Data.position = unit.Data.birthPosition;
                    roadPath.position = unit.Data.birthPosition;
                    unit.gameObject.transform.position = unit.Data.position;
                    unit.gameObject.transform.forward = unit.Data.forward;
                    unit.Data.isInBirthPosition = true;
                }
                
                unit.Data.SetIsInSkill(false);
                unit.Data.SetIsInAttack(false);
                unit.Data.SetIsCanMove(true);
                
                unit.Data.controlType = EControlType.None;
                //Debug.LogError(unit.Data.id + " " + position);
            }
            else if (type == ETransmitType.RpgPrepare)
            {
                if (PveGlobalVlues.EnemyRunIntoBattle)
                {
                    var position = unit.Data.birthPosition + new Vector3(5, 0, 0);
                    unit.Data.position = position;
                    roadPath.position = position;
                    unit.Data.moveState = 2;
                    unit.Data.isInBirthPosition = false;
                }
                else
                {
                    unit.Data.moveState = 0;
                }
            }
            roadPath?.OnTransmit(type,arg);
        }

        private void AddMortalAction()
        {
            return;
            var orders = unit.Data.GetOrders();
            if (orders.Count > 0)
            {
                return;
            }
            var order = ClassManager.Get<UnitOrder>();
            if (Random.Range(0, 1f) > 0.5)
            {
                order.targetPosition = unit.Data.position + new Vector3(Random.Range(-unit.Data.searchRange, unit.Data.searchRange), 0,
                                           Random.Range(-unit.Data.searchRange, unit.Data.searchRange));
                order.type = UnitOrder.EOrderType.MoveToPosition;
            }
            else
            {
                order.type = UnitOrder.EOrderType.Park;
                order.lastTime = Random.Range(1f, 5f);
            }
            AddOrder(order);
        }
           
        
        protected void ObeyOrder(UnitOrder order)
        {
            if (order.type == UnitOrder.EOrderType.MoveToPosition)
            {
                unit.Data.SetTargetPosition(order.targetPosition);
                var orders = unit.Data.GetOrders();
                for (int i = 0; i < orders.Count; i++)
                {
                    if (orders[i].type == order.type)
                    {
                        orders.RemoveAt(i);
                        break;
                    }
                }
                unit.Data.SetIsCanMove(true);
                if (roadPath is BattleUnitRoadPath path)
                {
                    path.needRepath = true;
                    //path.needShowPath = true;
                }
            }
            else if (order.type == UnitOrder.EOrderType.AttackToTarget)
            {
                unit.Data.SetLockTarget(order.target);
                unit.Data.SetTargetPosition(order.target.Data.position);
                unit.Data.ClearOrders();
                unit.Data.SetIsCanMove(true);
            }
            else if (order.type == UnitOrder.EOrderType.Patrol)
            {
                unit.Data.patrolPosition = order.targetPosition;
                //unit.Data.SetTargetPosition(order.targetPosition);
                //unit.Data.SetIsInAttack(false);
                //unit.Data.SetIsCanMove(true);
                var forward = unit.Data.patrolPosition - unit.Data.position;
                var angle = Vector3.Angle(unit.Data.forward, forward);
                float time = Vector3.Distance(unit.Data.patrolPosition, unit.Data.position) / 4;
                var angleSpeed = angle / time;
                if (time > 3 || angle < 20)
                {
                    angleSpeed = 100;
                }
                else
                {
                    angleSpeed = 100;
                }

                //unit.Data.angleSpeed = 1000;//angleSpeed;
                unit.Data.SetTargetPosition(unit.Data.targetPosition);
                //PveCameraManager.Instance.PveToNext(forward);
                //if (roadPath is SimpleRoadPath path)
                {
                    roadPath.UpdateAStarPath(unit.Data.position,unit.Data.targetPosition);
                }
            }
            else if (order.type == UnitOrder.EOrderType.Park)
            {
                if (order.startTime == 0)
                {
                    order.startTime = TimeManager.logicTime;
                }
            }
            else if (order.type == UnitOrder.EOrderType.Skill)
            {
                //unit.Data.ClearOrders();
                /*if (unit.Data.IsInSkill())
                {
                    return;
                }*/
                if (unit.Data.IsInMainSkill())
                {
                    return;
                }

                if (unit.Data.IsInControl())
                {
                    return;
                }

                if (unit.Data.isReloading)
                {
                    unit.Data.isReloading = false;
                }
                unit.Data.RemoveOrder(order);
                var skillArg = ClassManager.Get<SkillTransmitArg>();
                skillArg.skillId = order.skillArgs.id;
                skillArg.skillIndex = order.skillArgs.globalSkillIndex;
                skillArg.targetForward = order.skillArgs.targetForward;
                skillArg.targetPosition = order.skillArgs.targetPosition;
                skillArg.targetUnits = order.skillArgs.targetList;
                unit.Transmit(ETransmitType.Skill,skillArg);
                ClassManager.Free(skillArg);
            }
            else if (order.type == UnitOrder.EOrderType.Follow)
            {
                unit.Data.ClearOrders();
                unit.Data.followOffset = PveUtils.GetSelfPvePosOffset(unit.Data.index);
                unit.Data.followOffsetDistance = unit.Data.followOffset.magnitude;
                unit.Data.followOffsetDistanceSqr = unit.Data.followOffsetDistance * unit.Data.followOffsetDistance;
                unit.Data.followTarget = order.target;
            }
            else if (order.type == UnitOrder.EOrderType.SpecialCase)
            {
                roadPath.DoSpecialCase(order);
            }
        }
        
        protected void AddOrder(UnitOrder order)
        {
            if (order.type == UnitOrder.EOrderType.Skill)
            {
                unit.Data.AddOrder(order);
                ObeyOrder(order);
                return;
            }
            ObeyOrder(order);
            if (order.type == UnitOrder.EOrderType.SpecialCase)
            {
                unit.Data.AddOrder(order,true);
            }
            else
            {
                unit.Data.AddOrder(order);
            }
        }
    }
}
